#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QApplication>
#include <QDebug>
#include <QThread>
#include <QMessageBox>
#include <gio/gio.h>
#include <QRegularExpression>
#include <QTextCursor>
#include <QTextBlock>
#include <QScrollBar>
#include "customroledialog.h"
#include <QTextDocument>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QDir>
#include <QTimer>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , textSession(nullptr)
    , textConfig(nullptr)
    , asrSession(nullptr)
    , ttsSession(nullptr)
    , speechModelConfig(nullptr)
    , asrAudioConfig(nullptr)
    , ttsAudioConfig(nullptr)
    , mainLoop(nullptr)
    , replyBuffer("")
    , contentBuffer("")
    , ttsOutputFile(QDir::tempPath() + "/tts_output.pcm")
    , isRecording(false)
{
    ui->setupUi(this);

    // 启用富文本显示
    ui->chatDisplay->setAcceptRichText(true);

    // 加载 QSS 样式
    QFile file(":/resources/style.qss");
    if (file.open(QFile::ReadOnly)) {
        QString styleSheet = QLatin1String(file.readAll());
        qApp->setStyleSheet(styleSheet);
        file.close();
    } else {
        qDebug() << "Failed to load style.qss";
    }

    // 初始化角色选择
    ui->roleComboBox->addItems({"默认", "律师", "教师", "程序员", "作家"});

    // 初始化角色提示词
    rolePrompts["默认"] = "";
    rolePrompts["律师"] = "你是一名专业的律师，擅长解答法律问题，提供准确的法律建议。请以严谨、专业的语气回答用户的问题。";
    rolePrompts["教师"] = "你是一名知识渊博的教师，擅长讲解学术知识，辅导学生学习。请以耐心、清晰的语气回答用户的问题。";
    rolePrompts["程序员"] = "你是一名经验丰富的程序员，擅长解决代码问题，提供编程建议。请以技术性、实用的语气回答用户的问题。";
    rolePrompts["作家"] = "你是一名富有创意的作家，擅长创作故事、润色文章。请以生动、文学化的语气回答用户的问题。";

    // 初始化文本和语音会话
    initTextSession();
    initSpeechSession();

    // 连接信号和槽
    connect(ui->sendButton, &QPushButton::clicked, this, &MainWindow::on_sendButton_clicked);
    connect(ui->startRecordButton, &QPushButton::clicked, this, &MainWindow::on_startRecordButton_clicked);
    connect(ui->stopRecordButton, &QPushButton::clicked, this, &MainWindow::on_stopRecordButton_clicked);
    connect(ui->playVoiceButton, &QPushButton::clicked, this, &MainWindow::on_playVoiceButton_clicked);
    connect(ui->settingsButton, &QPushButton::clicked, this, &MainWindow::on_settingsButton_clicked);
    connect(ui->customRoleButton, &QPushButton::clicked, this, &MainWindow::on_customRoleButton_clicked);
    connect(ui->roleComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &MainWindow::on_roleComboBox_currentIndexChanged);
}

MainWindow::~MainWindow()
{
    if (textSession) {
        genai_text_stop_chat(textSession);
        genai_text_destroy_session(&textSession);
    }
    if (textConfig) {
        chat_model_config_destroy(&textConfig);
    }
    if (asrSession) {
        speech_recognizer_stop_continuous_recognition_async(asrSession);
        speech_recognizer_destroy_session(&asrSession);
    }
    if (ttsSession) {
        speech_synthesizer_stop_speaking(ttsSession);
        speech_synthesizer_destroy_session(&ttsSession);
    }
    if (speechModelConfig) {
        speech_model_config_destroy(&speechModelConfig);
    }
    if (asrAudioConfig) {
        audio_config_destroy(&asrAudioConfig);
    }
    if (ttsAudioConfig) {
        audio_config_destroy(&ttsAudioConfig);
    }
    if (mainLoop) {
        g_main_loop_quit(mainLoop);
        g_main_loop_unref(mainLoop);
    }
    delete ui;
}

/*
 *******************
 *
 *  语音识别和合成模块
 *
 ********************/

void MainWindow::initSpeechSession()
{

    // 创建模型配置
    speechModelConfig = speech_model_config_create();
    if (!speechModelConfig) {
        qDebug() << "Failed to create SpeechModelConfig";
        ui->chatDisplay->append("错误: 无法创建语音模型配置，请检查 SDK 环境");
        return;
    }

    // 设置模型名称和部署类型
    speech_model_config_set_name(speechModelConfig, "百度-语音大模型"); //讯飞-语音大模型
    speech_model_config_set_deploy_type(speechModelConfig, ModelDeployType::PublicCloud);

    // 初始化语音识别会话
    asrSession = speech_recognizer_create_session();
    if (!asrSession) {
        qDebug() << "Failed to create SpeechRecognitionSession";
        ui->chatDisplay->append("错误: 无法创建语音识别会话，请检查 SDK 环境");
        speech_model_config_destroy(&speechModelConfig);
        speechModelConfig = nullptr;
        return;
    }

    speech_recognizer_set_model_config(asrSession, speechModelConfig);
    int asrInitResult = speech_recognizer_init_session(asrSession);
    if (asrInitResult != 0) {
        qDebug() << "Failed to initialize ASR session, error code:" << asrInitResult;
        ui->chatDisplay->append(QString("错误: 初始化语音识别会话失败，错误码: %1").arg(asrInitResult));
        speech_recognizer_destroy_session(&asrSession);
        asrSession = nullptr;
        speech_model_config_destroy(&speechModelConfig);
        speechModelConfig = nullptr;
        return;
    }

    // 设置语音识别音频配置（默认麦克风）
    asrAudioConfig = audio_config_create_continuous_audio_input_from_default_microphone();
    if (!asrAudioConfig) {
        qDebug() << "Failed to create ASR AudioConfig";
        ui->chatDisplay->append("错误: 无法创建语音识别音频配置，可能是麦克风权限或设备问题");
        speech_recognizer_destroy_session(&asrSession);
        asrSession = nullptr;
        speech_model_config_destroy(&speechModelConfig);
        speechModelConfig = nullptr;
        return;
    }
    speech_recognizer_set_audio_config(asrSession, asrAudioConfig);

    // 设置语音识别回调
    speech_recognizer_result_set_callback(asrSession, asrCallback, this);

    // 初始化语音合成会话
    ttsSession = speech_synthesizer_create_session();
    if (!ttsSession) {
        qDebug() << "Failed to create SpeechSynthesizerSession";
        ui->chatDisplay->append("错误: 无法创建语音合成会话，请检查 SDK 环境");
        speech_recognizer_destroy_session(&asrSession);
        asrSession = nullptr;
        speech_model_config_destroy(&speechModelConfig);
        speechModelConfig = nullptr;
        audio_config_destroy(&asrAudioConfig);
        asrAudioConfig = nullptr;
        return;
    }

    speech_synthesizer_set_model_config(ttsSession, speechModelConfig);
    int ttsInitResult = speech_synthesizer_init_session(ttsSession);
    if (ttsInitResult != 0) {
        qDebug() << "Failed to initialize TTS session, error code:" << ttsInitResult;
        ui->chatDisplay->append(QString("错误: 初始化语音合成会话失败，错误码: %1").arg(ttsInitResult));
        speech_recognizer_destroy_session(&asrSession);
        asrSession = nullptr;
        speech_synthesizer_destroy_session(&ttsSession);
        ttsSession = nullptr;
        speech_model_config_destroy(&speechModelConfig);
        speechModelConfig = nullptr;
        audio_config_destroy(&asrAudioConfig);
        asrAudioConfig = nullptr;
        return;
    }

    // 设置语音合成音频配置（输出到PCM文件）
    ttsAudioConfig = audio_config_create_audio_output_from_pcm_file_name(ttsOutputFile.toUtf8().constData());
    if (!ttsAudioConfig) {
        qDebug() << "Failed to create TTS AudioConfig";
        ui->chatDisplay->append("错误: 无法创建语音合成音频配置");
        speech_recognizer_destroy_session(&asrSession);
        asrSession = nullptr;
        speech_synthesizer_destroy_session(&ttsSession);
        ttsSession = nullptr;
        speech_model_config_destroy(&speechModelConfig);
        speechModelConfig = nullptr;
        audio_config_destroy(&asrAudioConfig);
        asrAudioConfig = nullptr;
        return;
    }
    audio_config_set_input_audio_rate(ttsAudioConfig, 16000); // 设置采样率
    speech_synthesizer_set_audio_config(ttsSession, ttsAudioConfig);

    // 设置语音合成回调
    speech_synthesizer_result_set_callback(ttsSession, ttsCallback, this);

    qDebug() << "Speech sessions initialized successfully";
}

void MainWindow::asrCallback(SpeechRecognitionResult *result, void *user_data)
{
    MainWindow *window = static_cast<MainWindow*>(user_data);
    SpeechResultReason reason = speech_recognition_result_get_reason(result);
    const char *text = speech_recognition_result_get_text(result);
    int errorCode = speech_recognition_result_get_error_code(result);
    const char *errorMessage = speech_recognition_result_get_error_message(result);

    qDebug() << "ASR callback, reason:" << (int)reason
             << ", errorCode:" << errorCode
             << ", message:" << (errorMessage ? errorMessage : "None");

    switch (reason) {
    case SPEECH_RECOGNITION_STARTED: // 2
        qDebug() << "调试: 语音识别已启动";
        break;
    case SPEECH_RECOGNIZING:
        if (text) {
            qDebug() << "调试: 正在识别中间结果: " + QString::fromUtf8(text);
            window->ui->chatInput->setText(QString::fromUtf8(text)); // 实时更新输入框
        }
        break;
    case SPEECH_RECOGNIZED:
        if (errorCode == 0 && text) {
            QString recognizedText = QString::fromUtf8(text);
            qDebug() << "ASR final result:" << recognizedText;
            window->ui->chatInput->setText(recognizedText); // 设置最终结果
            qDebug() << "语音识别完成，结果已填入输入框";
        } else {
            window->ui->chatDisplay->append(QString("错误: 语音识别失败 - 错误码: %1, 信息: %2").arg(errorCode).arg(QString::fromUtf8(errorMessage ? errorMessage : "未知错误")));
        }
        break;
    case SPEECH_RECOGNITION_COMPLETED:
        qDebug() << "调试: 语音识别会话完成";
        if (!window->ui->chatInput->text().isEmpty()) {
            qDebug() << "提示: 语音识别结果已准备好，请编辑输入框内容后发送";
        } else {
            qDebug() << "警告: 未检测到有效语音输入";
        }
        break;
    case SPEECH_ERROR_OCCURRED:
        QString errorMsg = QString("错误: 语音识别失败 - 错误码: %1, 信息: %2").arg(errorCode).arg(QString::fromUtf8(errorMessage ? errorMessage : "未知错误"));
        window->ui->chatDisplay->append(errorMsg);
        if (errorCode == 6) {
            window->ui->chatDisplay->append("提示: 请检查系统麦克风权限（设置 -> 隐私 -> 麦克风）或确认麦克风设备是否被占用");
        }
        break;

    }
}

void MainWindow::ttsCallback(SpeechSynthesisResult *result, void *user_data)
{
    MainWindow *window = static_cast<MainWindow*>(user_data);
    SpeechResultReason reason = speech_synthesis_result_get_reason(result);
    int errorCode = speech_synthesis_result_get_error_code(result);
    const char *errorMessage = speech_synthesis_result_get_error_message(result);

    qDebug() << "TTS callback, reason:" << (int)reason
             << ", errorCode:" << errorCode
             << ", message:" << (errorMessage ? errorMessage : "None");

    switch (reason) {
    case SPEECH_SYNTHESIS_STARTED:
        qDebug() << "调试: 语音合成已启动";
        break;
    case SPEECH_SYNTHESIZING:
        qDebug() << "调试: 语音合成进行中";
        break;
    case SPEECH_SYNTHESIS_COMPLETED:
        if (errorCode == 0) {
            qDebug() << "TTS audio generated at:" << window->ttsOutputFile;

            // 直接播放生成的音频
            QMediaPlayer *player = new QMediaPlayer(window);
            QMediaPlaylist *playlist = new QMediaPlaylist;
            playlist->addMedia(QUrl::fromLocalFile(window->ttsOutputFile));
            playlist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
            player->setPlaylist(playlist);
            player->setVolume(50);
            player->play();

//            connect(player, &QMediaPlayer::stateChanged, window, [player](QMediaPlayer::State state) {
//                if (state == QMediaPlayer::StoppedState) {
//                    delete player; // 播放完成后释放资源
//                }
//            });
        } else {
            qDebug() << "TTS error on completion:" << errorMessage;
            window->ui->chatDisplay->append("错误: 语音合成完成但有错误 - " + QString::fromUtf8(errorMessage ? errorMessage : "未知错误"));
        }
        break;
    case SPEECH_ERROR_OCCURRED:
        qDebug() << "TTS error:" << errorMessage;
        window->ui->chatDisplay->append("错误: 语音合成失败 - " + QString::fromUtf8(errorMessage ? errorMessage : "未知错误"));
        break;
    default:
        qDebug() << "Unknown TTS reason:" << (int)reason;
        break;
    }
}

void MainWindow::on_startRecordButton_clicked()
{
    if (isRecording) {
        qDebug() << "Already recording";
        return;
    }

    if (!asrSession) {
        ui->chatDisplay->append("错误: 语音识别会话未初始化，请检查 SDK 环境");
        return;
    }

    // 清空输入框，准备接收新识别结果
    ui->chatInput->clear();

    // 开始流式语音识别
    speech_recognizer_start_continuous_recognition_async(asrSession);
    isRecording = true;
    ui->startRecordButton->setEnabled(false);
    ui->stopRecordButton->setEnabled(true);
    ui->chatDisplay->append("开始录音...");
    qDebug() << "Recording started";

    // 设置60秒超时
    QTimer::singleShot(60 * 1000, this, [this]() {
        if (isRecording) {
            on_stopRecordButton_clicked();
            ui->chatDisplay->append("录音超时，已自动停止");
        }
    });
}

void MainWindow::on_stopRecordButton_clicked()
{
    if (!isRecording) {
        qDebug() << "Not recording";
        return;
    }

    if (!asrSession) {
        ui->chatDisplay->append("错误: 语音识别会话未初始化");
        return;
    }

    // 停止流式语音识别
    speech_recognizer_stop_continuous_recognition_async(asrSession);
    isRecording = false;
    ui->startRecordButton->setEnabled(true);
    ui->stopRecordButton->setEnabled(false);
    ui->chatDisplay->append("录音停止");
    qDebug() << "Recording stopped";
}

void MainWindow::on_playVoiceButton_clicked()
{
    if (!ttsSession) {
        ui->chatDisplay->append("错误: 语音合成会话未初始化");
        return;
    }

    on_stopRecordButton_clicked();

    // 获取最新的 AI 回复
    QString lastReply = contentBuffer.section("AI: ", -1).trimmed();

    if (lastReply.isEmpty()) {
        ui->chatDisplay->append("错误: 无可合成的 AI 回复，请先获取 AI 回复");
        return;
    }

    // 触发语音合成
    ui->chatDisplay->append("正在合成语音...");
    speech_synthesizer_synthesize_text_async(ttsSession, lastReply.toUtf8().constData(), lastReply.toUtf8().length());
    qDebug() << "TTS synthesis started for text:" << lastReply;
}

#include <QProcess>

void MainWindow::setUSBMicrophoneAsDefault()
{
    QString sourceName = "alsa_input.usb-SN0002_HIK_1080P_Camera_46000000_SN0002-02.mono-fallback";
    QProcess process;
    process.start("pactl", QStringList() << "set-default-source" << sourceName);
    process.waitForFinished();
    if (process.exitCode() != 0) {
        QString error = process.readAllStandardError();
        ui->chatDisplay->append("错误: 无法设置 USB 麦克风为默认输入源: " + error);
        qDebug() << "Failed to set default source:" << sourceName << ", error:" << error;
    } else {
        ui->chatDisplay->append("已设置 USB 摄像头麦克风为默认输入源: " + sourceName);
        qDebug() << "Set default source to:" << sourceName;
    }
}

void MainWindow::checkAvailableMicrophones()
{
    QProcess process;
    process.start("pactl list sources");
    process.waitForFinished();
    QString output = process.readAllStandardOutput();
    QStringList lines = output.split("\n");
    bool foundUSBMic = false;
    QString usbMicName = "alsa_input.usb-SN0002_HIK_1080P_Camera_46000000_SN0002-02.mono-fallback";
    for (const QString &line : lines) {
        if (line.contains(usbMicName)) {
            foundUSBMic = true;
            break;
        }
    }
    if (foundUSBMic) {
        setUSBMicrophoneAsDefault();
    } else {
        ui->chatDisplay->append("错误: 未找到 USB 摄像头麦克风");
        qDebug() << "USB microphone not found";
    }
}


/*
 *******************
 *
 *  文字识别模块
 *
 ********************/

void MainWindow::initTextSession()
{
    // 创建 GMainLoop
    mainLoop = g_main_loop_new(nullptr, false);

    QThread *loopThread = QThread::create([this] {
        g_main_loop_run(mainLoop);
    });
    loopThread->start();

    // 创建模型配置
    textConfig = chat_model_config_create();
    if (!textConfig) {
        qDebug() << "Failed to create ChatModelConfig";
        ui->chatDisplay->append("<font color='red'>错误: 无法创建模型配置，请检查 SDK 环境</font>");
        return;
    }

    // 尝试主模型
    QStringList modelNames = {"百度-ERNIE-Bot-4", "讯飞-Spark Max"};
    bool initSuccess = false;
    QString errorMessage;

    for (const QString &modelName : modelNames) {
        chat_model_config_set_name(textConfig, modelName.toUtf8().constData());
        chat_model_config_set_deploy_type(textConfig, ModelDeployType::PublicCloud);
        chat_model_config_set_top_k(textConfig, 0.5);

        // 创建会话
        textSession = genai_text_create_session();
        if (!textSession) {
            qDebug() << "Failed to create GenAiTextSession for model:" << modelName;
            errorMessage = "<font color='red'>错误: 无法创建文本会话，请检查 SDK 环境</font>";
            continue;
        }

        genai_text_set_model_config(textSession, textConfig);
        int initResult = genai_text_init_session(textSession);
        if (initResult == 0) {
            qDebug() << "Text session initialized successfully with model:" << modelName;
            initSuccess = true;
            break;
        } else {
            qDebug() << "Failed to initialize text session with model:" << modelName << ", error code:" << initResult;
            errorMessage = QString("<font color='red'>错误: 初始化 %1 模型失败，错误码: %2</font>").arg(modelName).arg(initResult);
            genai_text_destroy_session(&textSession);
            textSession = nullptr;
        }
    }

    if (!initSuccess) {
        ui->chatDisplay->append(errorMessage + "。请检查网络连接或 AI 模块配置");
        chat_model_config_destroy(&textConfig);
        textConfig = nullptr;
        return;
    }

    // 设置回调
    genai_text_result_set_callback(textSession, textCallback, this);

    // 设置初始角色提示词
    QString currentRole = ui->roleComboBox->currentText();
    if (rolePrompts.contains(currentRole) && !rolePrompts[currentRole].isEmpty()) {
        genai_text_set_chat_system_prompt(textSession, rolePrompts[currentRole].toUtf8().constData());
        qDebug() << "Set system prompt for role:" << currentRole;
    }
}

void MainWindow::textCallback(ChatResult *result, void *user_data)
{
    MainWindow *window = static_cast<MainWindow*>(user_data);
    const char *message = chat_result_get_assistant_message(result);
    int errorCode = chat_result_get_error_code(result);
    const char *errorMessage = chat_result_get_error_message(result);

    if (errorCode == AISDK_NO_ERROR && message) {

        window->replyBuffer = QString::fromUtf8(message);
        window->contentBuffer += window->replyBuffer;

        QString htmlBuffer = window->markdownToHtml(window->contentBuffer);
        window->ui->chatDisplay->setHtml(htmlBuffer);

        qDebug() << window->contentBuffer;
        qDebug() << htmlBuffer;

        QScrollBar *scrollBar = window->ui->chatDisplay->verticalScrollBar();
        scrollBar->setValue(scrollBar->maximum());

    } else {
        // 错误处理
        window->ui->chatDisplay->append("错误: " + QString::fromUtf8(errorMessage));
        window->replyBuffer.clear();
    }
}

QString MainWindow::markdownToHtml(const QString &markdown) {
    QTextDocument doc;

    QFont font;
    font.setPointSize(12);

    doc.setDefaultFont(font);
    doc.setMarkdown(markdown);

    return doc.toHtml();
}

void MainWindow::addCustomRole(const QString &roleName, const QString &prompt)
{
    if (roleName.isEmpty() || rolePrompts.contains(roleName)) {
        QMessageBox::warning(this, "错误", "角色名称不能为空或已存在");
        return;
    }

    rolePrompts[roleName] = prompt;
    ui->roleComboBox->addItem(roleName);
    ui->roleComboBox->setCurrentText(roleName);
    ui->chatDisplay->append("已添加并切换到新角色: " + roleName);
}

void MainWindow::on_sendButton_clicked()
{
    QString input = ui->chatInput->text().trimmed();
    if (!input.isEmpty()) {
        if (!textSession) {
            ui->chatDisplay->append("错误: 文本会话未初始化，请检查模型配置");
            return;
        }
        contentBuffer += "用户: " + input + "  " + "AI: ";
        // 显示用户输入
        ui->chatDisplay->append(contentBuffer);

        // 发送请求
        genai_text_chat_async(textSession, input.toUtf8().constData());

        replyBuffer.clear();
        ui->chatInput->clear();
    }
}

void MainWindow::on_settingsButton_clicked() {}

void MainWindow::on_customRoleButton_clicked()
{
    CustomRoleDialog dialog(this);
    if (dialog.exec() == QDialog::Accepted) {
        QString roleName = dialog.getRoleName();
        QString prompt = dialog.getPrompt();
        addCustomRole(roleName, prompt);
    }
}

void MainWindow::on_roleComboBox_currentIndexChanged(int index)
{
    QString currentRole = ui->roleComboBox->itemText(index);
    if (rolePrompts.contains(currentRole)) {
        genai_text_clear_chat_history_messages(textSession);
        if (!rolePrompts[currentRole].isEmpty()) {
            genai_text_set_chat_system_prompt(textSession, rolePrompts[currentRole].toUtf8().constData());
        } else {
            genai_text_set_chat_system_prompt(textSession, "");
        }
        ui->chatDisplay->append("已切换到角色: " + currentRole);
    }
}
